import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class SemaphoreTest {
    // Semaphore 一个技术信号量，信号量维护一个许可集合，通过acquire()和release()来获取释放须贺证，只有通过aquire获取
    // 了许可证的线程才能执行，否则阻塞，通过release释放许可证其他线程才能进行获取
    // 公平性，灭有办法保证线程能够公平的从信号量中过去许可，也就是说，无法保证第一个调用acquire()的
    // 线程会是第一个获的一个许可的线程，如果第一个线程在等待一个许可时发生阻塞，而第二个线程前来索要一个许可的时候
    // 刚好有一个许可被释放出来，那么他就可能会在第一个线程之前获得许可，如果你想要强制公平，Semaphoer有一个
    // 布尔类型的参数，通过这个参数以告知Semaphore是否要强制公平，强制共批评会印象到并发性能，
    public static void main(String[] args) {
        ExecutorService exec  = Executors.newCachedThreadPool();
        // 设置许可证数量，默认是不公平的
        // final Semaphore semaphoreTest = new java.util.concurrent.Semaphore(2);
        // 强制公平
        final Semaphore semp = new java.util.concurrent.Semaphore(2,true);
        // 模拟多个客户端并发访问
        for (int i = 0; i < 5; i++) {
            exec.execute(()->{
                try {
                    System.out.println(Thread.currentThread().getName()+"尝试获取");
                    semp.acquire();
                    System.out.println(Thread.currentThread().getName()+"获取许可");
                    Thread.sleep(1000);
                    System.out.println(Thread.currentThread().getName()+"释放许可");
                    semp.release();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
        exec.shutdown();

    }
}
